<script setup lang="ts">
  import {
    DeviceStatusEnum,
    getVirtualDeviceApi,
    listDeviceParamApi,
    saveUpdateDeviceParamApi,
    sendParamApi,
    sendEventApi,
    sendNtpApi,
    sendWarnApi,
    setDeviceLatLngApi,
    startSendParamTaskApi,
    updateDeviceStatusApi,
    uploadTopologyApi,
  } from '@/api/hc/virtualDevice';
  import { PageWrapper } from '@/components/Page';
  import { nextTick, onMounted, onUnmounted, ref, unref } from 'vue';
  import { Persistent } from '@/utils/cache/persistent';
  import { PARAM_NAME_KEY, SN_KEY } from '@/enums/cacheEnum';
  import { useMessage } from '@/hooks/web/useMessage';
  import dayjs from 'dayjs';
  import { useScript } from '@/hooks/web/useScript';
  import { DescItem, Description } from '@/components/Description';
  import { getVerBySnApi, GetVerBySnRes } from '@/api/hc/virtualDeviceModule';
  import { useRoute } from 'vue-router';
  import { message, SelectProps } from 'ant-design-vue';
  import { IotVirtualDevice, updateVirtualDeviceByIdApi } from '@/api/hc/iotVirtualDevice';

  let deviceImageList = ref<[]>([]);
  const deviceInfo = ref<IotVirtualDevice>({
    warnBitList: [],
    lat: '25.619429',
    lng: '99.409586',
  });

  const warnOptions = ref<SelectProps['options']>([]);

  for (let i = 0; i < 64; i++) {
    const value = i;
    warnOptions.value.push({
      label: i,
      value: value,
    });
  }
  const warnValue = ref<number[]>([]);

  function sendWarn() {
    const warnBitList: number[] = [];
    for (let i = 0; i < 64; i++) {
      if (warnValue.value.includes(i) || warnValue.value.includes('' + i)) {
        warnBitList.push(1);
      } else {
        warnBitList.push(0);
      }
    }

    sendWarnApi({
      sn: sn.value,
      warnBitList: warnBitList,
    }).then((res) => {
      createMessage.info('sendWarn ' + res);
    });
  }

  const event = ref<number>(0);

  function sendEvent() {
    sendEventApi({
      sn: sn.value,
      event: event.value,
    }).then((res) => {
      createMessage.info('sendEvent ' + res);
    });
  }

  function startSendDpParamTask() {
    startSendParamTaskApi({
      sn: deviceInfo.value.sn,
      cron: deviceInfo.value.uploadCron,
      func: 0,
    }).then((res) => {
      message.success('成功', res);
      pageGetAll();
    });
  }

  let sn = ref<string>('');
  let paramName = ref<string>(Persistent.getLocal(PARAM_NAME_KEY) || '');

  function submit() {
    getVirtualDevice();
    listDeviceParam();
  }

  const autoRefresh = ref<boolean>(true);

  let intervalId;

  function init() {
    getVirtualDevice();
    listDeviceParam();
    intervalId = setInterval(() => {
      if (autoRefresh.value) {
        listDeviceParam();
      }
    }, 20000);
  }

  onUnmounted(() => {
    console.log('onUnmounted');
    clearInterval(intervalId);
  });

  onMounted(() => {
    console.log('onMounted');
    const route = useRoute();
    if (route.params.sn && route.params.sn !== ':sn') {
      sn.value = route.params.sn;
    }
    console.log(route.params);
    console.log(route.query);
  });

  function updateDeviceStatus(sn: string, deviceStatus: string) {
    updateDeviceStatusApi({
      snList: [sn],
      deviceStatus: DeviceStatusEnum[deviceStatus],
    }).then((res) => {
      createMessage.info('updateDeviceStatus ' + res);
      init();
    });
  }

  function sendNtp() {
    sendNtpApi({
      sn: sn.value,
    }).then((res) => {
      createMessage.info('sendNtp ' + res);
    });
  }

  function getVirtualDevice() {
    getVirtualDeviceApi({
      sn: sn.value,
    }).then((res) => {
      deviceInfo.value = res;
      event.value = res.event;
      warnValue.value = [];
      for (let index in deviceInfo.value.warnBitList) {
        const item = deviceInfo.value.warnBitList[index];
        if (item === 1) {
          warnValue.value.push(index);
        }
      }
      var marker = new AMap.Marker({
        icon: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
        position: [res.lng, res.lat],
      });
      map.add(marker);
      map.setCenter([res.lng, res.lat]);
    });
  }

  function listDeviceParam() {
    listDeviceParamApi({
      sn: sn.value,
    }).then((res) => {
      const list = [];
      res.forEach((item) => {
        if (item.name.indexOf(paramName.value) >= 0) {
          list.push(item);
        }
      });
      deviceImageList.value = list;
    });
  }

  function paramNameChange() {
    Persistent.setLocal(PARAM_NAME_KEY, paramName.value);
  }

  const { createMessage } = useMessage();

  function updateParam(key: string, val: object) {
    const paramMap = {};
    paramMap[key] = val;

    saveUpdateDeviceParamApi({
      sn: sn.value,
      paramMap,
    }).then((res) => {
      createMessage.info('updateParam ' + res);
      listDeviceParam();
    });
  }

  function sendDpParam() {
    sendParamApi({
      sn: sn.value,
      func: 0,
    }).then((res) => {
      createMessage.info('sendDpParam ' + res);
    });
  }

  function sendInfoParam() {
    sendParamApi({
      sn: sn.value,
      func: 1,
    }).then((res) => {
      createMessage.info('sendInfoParam ' + res);
    });
  }

  function uploadTopology() {
    uploadTopologyApi({
      sn: sn.value,
    }).then((res) => {
      createMessage.info('uploadTopology ' + res);
    });
  }

  const deviceImageColumns = [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      // scopedSlots: {
      //   filterDropdown: 'filterDropdown',
      //   filterIcon: 'filtericon',
      //   customRender: 'customRender',
      // },
      // onFilter: (value, record) => {
      //   record.name.toString().toLowerCase().includes(value.toLowerCase());
      // },
      // onFilterDropdownVisibleChange: (visible) => {
      //   if (visible) {
      //     setTimeout(() => {
      //       this.searchInput.focus();
      //     });
      //   }
      // },
    },
    {
      title: '类型',
      dataIndex: 'paramType',
      key: 'paramType',
    },
    {
      title: '值',
      dataIndex: 'val',
      key: 'val',
    },
    {
      title: '单位',
      dataIndex: 'unit',
      key: 'unit',
    },
    {
      title: 'code',
      dataIndex: 'paramCode',
      key: 'paramCode',
    },
    {
      title: 'key',
      dataIndex: 'paramKey',
      key: 'paramKey',
    },
    {
      title: '时间',
      dataIndex: 'ts',
      key: 'ts',
    },
  ];

  const A_MAP_URL =
    'https://webapi.amap.com/maps?v=1.4.15&key=99c56da62af9ce27de33875651f8cfb6&plugin=AMap.MouseTool';

  const wrapRef = ref<HTMLDivElement | null>(null);
  const { toPromise } = useScript({ src: A_MAP_URL });

  let map;
  let AMap;

  async function initMap() {
    await toPromise();
    await nextTick();
    const wrapEl = unref(wrapRef);
    if (!wrapEl) return;
    AMap = (window as any).AMap;
    map = new AMap.Map(wrapEl, {
      zoom: 11,
      // center: [lng.value, lat.value],
      // viewMode: '3D',
    });
    map.on('click', (e) => {
      console.log('e', e.lnglat);
      var marker = new AMap.Marker({
        icon: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
        position: [e.lnglat.lng, e.lnglat.lat],
      });
      map.add(marker);
      deviceInfo.value.lat = e.lnglat.lat;
      deviceInfo.value.lng = e.lnglat.lng;
      setDeviceLatLngApi({
        sn: sn.value,
        lat: e.lnglat.lat,
        lng: e.lnglat.lng,
      });
    });
  }

  onMounted(async () => {
    await initMap();
    init();
    getVerBySn();
  });

  function getVerBySn() {
    getVerBySnApi({
      sn: sn.value,
    }).then((res) => {
      moduleData.value = res;
    });
  }

  const moduleData = ref<GetVerBySnRes>();

  const moduleSchema: DescItem[] = [
    {
      field: 'iotAppVer',
      label: 'iotAppVer',
    },
    {
      field: 'iotOsVer',
      label: 'iotOsVer',
    },
    {
      field: 'dspBackVer',
      label: 'dspBackVer',
    },
    {
      field: 'dspFrontVer',
      label: 'dspFrontVer',
    },
    {
      field: 'armVer',
      label: 'armVer',
    },
  ];

  function updateVirtualDevice() {
    updateVirtualDeviceByIdApi(deviceInfo.value).then((res) => {
      createMessage.info('updateVirtualDevice ' + res);
    });
  }
</script>

<template>
  <div class="p-1">
    <a-space>
      <a-input v-model:value="sn" @change="snChange" />
      <a-input v-model:value="paramName" @change="paramNameChange" />
      <a-button type="primary" @click="submit">获取</a-button>
      <a-button type="primary" @click="sendNtp">NTP</a-button>
      <a-button type="primary" @click="sendDpParam">上报DP</a-button>
      <a-button type="primary" @click="sendInfoParam">上报Info</a-button>
      <a-button type="primary" @click="uploadTopology">上报拓扑</a-button>

      <a-button
        v-if="deviceInfo.deviceStatus === 'ONLINE'"
        type="primary"
        @click="updateDeviceStatus(deviceInfo.sn, 'OFFLINE')"
        >关闭设备
      </a-button>
      <a-button
        v-else-if="deviceInfo.deviceStatus === 'OFFLINE'"
        type="primary"
        @click="updateDeviceStatus(deviceInfo.sn, 'ONLINE')"
        >开启设备
      </a-button>
      <a-button v-else disabled>未知状态</a-button>
    </a-space>
    <a-space>
      <a-input disabled v-model:value="deviceInfo.lat" />
      <a-input disabled v-model:value="deviceInfo.lng" />
    </a-space>
    <div ref="wrapRef" style="height: 150px" class="w-full"></div>
    <Description
      size="middle"
      title="模块版本"
      :bordered="false"
      :column="3"
      :data="moduleData"
      :schema="moduleSchema"
    />
    <PageWrapper>
      <a-form :model="deviceInfo" layout="inline">
        <a-form-item label="id">
          <a-input v-model:value="deviceInfo.id" disabled />
        </a-form-item>
        <a-form-item label="pn">
          <a-input v-model:value="deviceInfo.pn" />
        </a-form-item>
        <a-form-item label="keepOnline">
          <a-input v-model:value="deviceInfo.keepOnline" />
        </a-form-item>
        <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
          <a-button type="primary" @click="updateVirtualDevice">保存</a-button>
        </a-form-item>
      </a-form>
    </PageWrapper>

    <PageWrapper title="告警配置" contentBackground>
      <a-space>
        <a-select
          :allow-clear="true"
          v-model:value="warnValue"
          mode="multiple"
          style="width: 300px"
          placeholder="Select Item..."
          :options="warnOptions"
        />
        <a-button type="primary" @click="sendWarn">发送</a-button>
      </a-space>

      <!--      <a-flex wrap="wrap" gap="small">-->
      <!--        <template v-for="(item, index) in deviceInfo.warnBitList" :key="index">-->
      <!--          <span style="line-height: 30px">{{ index }}:</span>-->
      <!--          <a-select ref="select" :value="item" style="width: 80px">-->
      <!--            <a-select-option :value="0">0</a-select-option>-->
      <!--            <a-select-option :value="1">1</a-select-option>-->
      <!--          </a-select>-->
      <!--        </template>-->
      <!--      </a-flex>-->
    </PageWrapper>

    <PageWrapper title="事件" contentBackground>
      <a-space>
        <a-input v-model:value="event" style="width: 300px" />
        <a-button type="primary" @click="sendEvent">发送</a-button>
      </a-space>
    </PageWrapper>

    <PageWrapper title="dp上报频率" contentBackground>
      <a-space>
        <a-input v-model:value="deviceInfo.uploadCron" style="width: 300px" />
        <a-button type="primary" @click="startSendDpParamTask">确定</a-button>
      </a-space>
    </PageWrapper>

    <PageWrapper title="设备镜像" contentBackground>
      <a-switch
        v-model:checked="autoRefresh"
        checked-children="自动刷新"
        un-checked-children="不"
      />
      <a-table :dataSource="deviceImageList" :columns="deviceImageColumns" :pagination="false">
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'val'">
            <a-space>
              <a-switch
                v-if="record.paramType === 'bool'"
                v-model:checked="record.val"
                :checked-value="1"
                :un-checked-value="0"
                @change="updateParam(record.paramKey, record.val)"
              />
              <div v-else class="flex">
                <a-input-number
                  v-if="record.paramType === 'int32'"
                  v-model:value="record.val"
                  class="mr"
                />
                <a-input-number
                  v-else-if="record.paramType === 'float'"
                  v-model:value="record.val"
                  class="mr"
                />
                <a-input-number
                  v-else-if="record.paramType === 'double'"
                  v-model:value="record.val"
                  class="mr"
                />
                <a-time-picker
                  v-else-if="record.paramType === 'time'"
                  v-model:value="record.val"
                  value-format="HH:mm:ss"
                  class="mr"
                />
                <a-date-picker
                  v-else-if="record.paramType === 'date'"
                  v-model:value="record.val"
                  class="mr"
                />
                <a-date-picker
                  value-format="x"
                  show-time
                  v-else-if="record.paramType === 'datetime'"
                  v-model:value="record.val"
                  class="mr"
                />
                <a-input v-else v-model:value="record.val" class="mr" />
                <a-button type="primary" @click="updateParam(record.paramKey, record.val)"
                  >更新
                </a-button>
              </div>
            </a-space>
          </template>
          <template v-else-if="column.key === 'ts'">
            <a>{{ dayjs(record.ts).format('YYYY-MM-DD HH:mm:ss') }}</a>
          </template>
        </template>
      </a-table>
    </PageWrapper>
  </div>
</template>

<style scoped lang="less"></style>
